package com.ruoyi.course.controller;

import java.util.Date;
import java.util.List;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.course.domain.AcademicYear;
import com.ruoyi.course.domain.TermCalendarEvents;
import com.ruoyi.course.domain.vo.TermVo;
import com.ruoyi.course.domain.vo.YearVo;
import com.ruoyi.course.service.impl.AcademicTermServiceImpl;
import com.ruoyi.course.service.impl.AcademicYearServiceImpl;
import com.ruoyi.course.service.impl.TermCalendarEventsServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.course.domain.AcademicTerm;
import com.ruoyi.course.service.IAcademicTermService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 学期信息Controller
 * 
 * @author chenxl
 * @date 2025-08-29
 */
@RestController
@RequestMapping("/course/term")
public class AcademicTermController extends BaseController
{
    @Autowired
    private IAcademicTermService academicTermService;
    @Autowired
    private AcademicYearServiceImpl academicYearService;
    @Autowired
    private TermCalendarEventsServiceImpl termCalendarEventsService;

    /**
     * 查询学期信息列表
     */
    //@PreAuthorize("@ss.hasPermi('course:term:list')")
    @GetMapping("/list")
    public TableDataInfo list(AcademicTerm academicTerm)
    {
        startPage();
        List<AcademicTerm> list = academicTermService.selectAcademicTermList(academicTerm);
        return getDataTable(list);
    }

    /**
     * 导出学期信息列表
     */
    @PreAuthorize("@ss.hasPermi('course:term:export')")
    @Log(title = "学期信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AcademicTerm academicTerm)
    {
        List<AcademicTerm> list = academicTermService.selectAcademicTermList(academicTerm);
        ExcelUtil<AcademicTerm> util = new ExcelUtil<AcademicTerm>(AcademicTerm.class);
        util.exportExcel(response, list, "学期信息数据");
    }

    /**
     * 获取学期信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('course:term:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return success(academicTermService.selectAcademicTermById(id));
    }

    /**
     * 新增学期信息
     */
    @PreAuthorize("@ss.hasPermi('course:term:add')")
    @Log(title = "学期信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AcademicTerm academicTerm)
    {
        return toAjax(academicTermService.insertAcademicTerm(academicTerm));
    }

    /**
     * 修改学期信息
     */
    @PreAuthorize("@ss.hasPermi('course:term:edit')")
    @Log(title = "学期信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AcademicTerm academicTerm)
    {
        return toAjax(academicTermService.updateAcademicTerm(academicTerm));
    }

    /**
     * 删除学期信息
     */
    @PreAuthorize("@ss.hasPermi('course:term:remove')")
    @Log(title = "学期信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(academicTermService.deleteAcademicTermByIds(ids));
    }

    /**
     * 新增学年、学期及关联事件（完整层级保存）
     * 包含事务管理，确保数据一致性
     */
    @PostMapping("/addYearTermEvent")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addYearTermEvent(@RequestBody YearVo yearVo) {
        // 1. 打印完整接收参数（生产环境可改为debug级别日志）
        System.out.println("=== 开始处理新增学年学期事件请求 ===");
        System.out.println("接收的YearVo完整参数: " + yearVo);

        try {
            // 2. 验证核心参数非空
            if (yearVo == null) {
                throw new RuntimeException("请求参数不能为空");
            }

            // 3. 验证学年信息
            AcademicYear year = yearVo.getYear();
            System.out.println("解析到的学年信息: " + year);
            if (year == null) {
                throw new RuntimeException("学年信息不能为空");
            }
            // 验证学年必填字段
            if (StringUtils.isBlank(year.getYearCode())) {
                throw new RuntimeException("学年编码(yearCode)不能为空");
            }
            if (year.getStartDate() == null) {
                throw new RuntimeException("学年开始时间(startDate)不能为空");
            }
            if (year.getEndDate() == null) {
                throw new RuntimeException("学年结束时间(endDate)不能为空");
            }

            // 4. 保存学年信息
            year.setId(IdUtils.fastSimpleUUID());
            Date now = new Date();
            year.setCreatedAt(now);
            year.setUpdatedAt(now);
            System.out.println("准备插入学年数据: " + year);

            int insertedYear = academicYearService.insertAcademicYear(year);
            System.out.println("学年插入影响行数: " + insertedYear);

            if (insertedYear <= 0) {
                throw new RuntimeException("学年保存失败，影响行数为0");
            }
            System.out.println("学年保存成功，ID: " + year.getId());

            // 5. 验证学期列表
            List<TermVo> termVoList = yearVo.getTerms();
            System.out.println("解析到的学期列表数量: " + (termVoList != null ? termVoList.size() : 0));

            if (termVoList == null || termVoList.isEmpty()) {
                throw new RuntimeException("至少需要添加一个学期");
            }

            // 6. 循环保存学期
            for (int i = 0; i < termVoList.size(); i++) {
                TermVo termVo = termVoList.get(i);
                System.out.println("处理第" + (i + 1) + "个学期: " + termVo);

                if (termVo == null || termVo.getTerm() == null) {
                    throw new RuntimeException("第" + (i + 1) + "个学期信息不能为空");
                }

                AcademicTerm term = termVo.getTerm();
                // 验证学期必填字段
                if (StringUtils.isBlank(term.getTermCode())) {
                    throw new RuntimeException("第" + (i + 1) + "个学期编码(termCode)不能为空");
                }
                if (StringUtils.isBlank(term.getTermName())) {
                    throw new RuntimeException("第" + (i + 1) + "个学期名称(termName)不能为空");
                }
                if (term.getStartDate() == null || term.getEndDate() == null) {
                    throw new RuntimeException("第" + (i + 1) + "个学期起止时间不能为空");
                }

                term.setId(IdUtils.fastSimpleUUID());
                term.setYearId(year.getId()); // 关联学年
                term.setCreatedAt(now);
                term.setUpdatedAt(now);
                System.out.println("准备插入学期数据: " + term);

                int insertedTerm = academicTermService.insertAcademicTerm(term);
                System.out.println("第" + (i + 1) + "个学期插入影响行数: " + insertedTerm);

                if (insertedTerm <= 0) {
                    throw new RuntimeException("第" + (i + 1) + "个学期保存失败: " + term.getTermName());
                }
                System.out.println("第" + (i + 1) + "个学期保存成功，ID: " + term.getId());

                // 7. 处理学期关联事件
                List<TermCalendarEvents> events = termVo.getEvents();
                System.out.println("第" + (i + 1) + "个学期的事件数量: " + (events != null ? events.size() : 0));

                if (events != null && !events.isEmpty()) {
                    for (int j = 0; j < events.size(); j++) {
                        TermCalendarEvents event = events.get(j);
                        System.out.println("处理第" + (i + 1) + "个学期的第" + (j + 1) + "个事件: " + event);

                        if (event == null) {
                            throw new RuntimeException("第" + (i + 1) + "个学期的第" + (j + 1) + "个事件信息不能为空");
                        }
                        // 验证事件必填字段
                        if (StringUtils.isBlank(event.getEventName())) {
                            throw new RuntimeException("第" + (i + 1) + "个学期的第" + (j + 1) + "个事件名称不能为空");
                        }
                        if (event.getStartTime() == null || event.getEndTime() == null) {
                            throw new RuntimeException("第" + (i + 1) + "个学期的第" + (j + 1) + "个事件时间不能为空");
                        }

                        event.setId(IdUtils.fastSimpleUUID());
                        event.setTermId(term.getId()); // 关联学期
                        event.setCreatedAt(now);
                        event.setUpdatedAt(now);
                        event.setCreatedBy("system");
                        event.setUpdatedBy("system");
                        System.out.println("准备插入事件数据: " + event);

                        int insertedEvent = termCalendarEventsService.insertTermCalendarEvents(event);
                        System.out.println("事件插入影响行数: " + insertedEvent);

                        if (insertedEvent <= 0) {
                            throw new RuntimeException("事件保存失败: " + event.getEventName());
                        }
                        System.out.println("事件保存成功，ID: " + event.getId());
                    }
                }
            }

            System.out.println("=== 所有数据保存成功 ===");
            return AjaxResult.success("学年、学期及事件保存成功");
        } catch (Exception e) {
            // 打印完整异常堆栈，方便定位问题
            System.err.println("=== 保存过程发生异常 ===");
            e.printStackTrace(); // 输出异常堆栈到控制台
            return AjaxResult.error("保存失败: " + e.getMessage());
        }
    }

    /*获取当前学年学期的信息详细getCurrentYearAndTerm*/
    @GetMapping("/getCurrentYearAndTerm")
    public AjaxResult getCurrentYearAndTerm() {
        return success(academicTermService.getCurrentYearAndTerm());
    }

}
